<?php defined('SYSPATH') or die('No direct script access.');

/**
 * Audio_scrobbler (Last_fM) Service Driver Library
 * http://www.last.fm/api
 *
 * $Id: Audioscrobbler.php 158 2008-10-27 16:05:20Z alex.aperez $
 *
 * @package		Service Module
 * @author		Alex Sancho
 * @copyright	(c) 2008 Alex Sancho
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 * 3. Neither the name of copyright holders nor the names of its
 *	  contributors may be used to endorse or promote products derived
 *	  from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

class Service_Audioscrobbler_Driver extends Service_Driver
{
	protected $api_url = "ws.audioscrobbler.com/1.0";
	protected $user = null;

	/**
	 *	__construct
	 * 
	 * @param array $config
	 * @return void
	 * @access public
	 * 
	 */
	public function __construct($config = array())
	{
		$config += Kohana::config('service.audioscrobbler');

		foreach($config as $key => $val)
			$this->$key = $val;
	}

	/**
	 * user_get_profile_information
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_profile_information()
	{
		return $this->api_call('/user/' . $this->user . '/profile.xml');
	}

	/**
	 * user_get_top_artists
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_top_artists()
	{
		return $this->api_call('/user/' . $this->user . '/topartists.xml');
	}

	/**
	 * user_get_top_albums
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_top_albums()
	{
		return $this->api_call('/user/' . $this->user . '/topalbums.xml');
	}

	/**
	 * user_get_top_tracks
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_top_tracks()
	{
		return $this->api_call('/user/' . $this->user . '/toptracks.xml');
	}

	/**
	 * user_get_top_tags
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_top_tags()
	{
		return $this->api_call('/user/' . $this->user . '/tags.xml');
	}

	/**
	 * user_get_top_tags_for_artist
	 * 
	 * @param string $artist
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_top_tags_for_artist($artist)
	{
		return $this->api_call('/user/' . $this->user . '/artisttags.xml?artist=' . $artist);
	}

	/**
	 * user_get_top_tags_for_album
	 * 
	 * @param string $artist
	 * @param string $album
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_top_tags_for_album($artist, $album)
	{
		return $this->api_call('/user/' . $this->user . '/albumtags.xml?artist=' . $artist . '&album=' . $album);
	}

	/**
	 * user_get_top_tags_for_track
	 * 
	 * @param string $artist
	 * @param string $track
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_top_tags_for_track($artist, $track)
	{
		return $this->api_call('/user/' . $this->user . '/tracktags.xml?artist=' . $artist . '&track=' . $track);
	}

	/**
	 * user_get_friends
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_friends()
	{
		return $this->api_call('/user/' . $this->user . '/friends.xml');
	}

	/**
	 * user_get_neighbours
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_neighbours()
	{
		return $this->api_call('/user/' . $this->user . '/neighbours.xml');
	}

	/**
	 * user_get_recent_tracks
	 * 
	 * @return string
	 * @access public
	 * 
	 */
	public function user_get_recent_tracks()
	{
		return $this->api_call('/user/' . $this->user . '/recenttracks.xml');
	}

	/**
	 * user_get_recent_banned_tracks
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_recent_banned_tracks()
	{
		return $this->api_call('/user/' . $this->user . '/recentbannedtracks.xml');
	}

	/**
	 * user_get_recent_loved_tracks
	 * 
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_recent_loved_tracks()
	{
		return $this->api_call('/user/' . $this->user . '/recentlovedtracks.xml');
	}

	/**
	 * user_get_weekly_chart_list
	 * 
	 * @return string
	 * @access public
	 * 
	 */
	public function user_get_weekly_chart_list()
	{
		return $this->api_call('/user/' . $this->user . '/weeklychartlist.xml');
	}

	/**
	 * user_get_weekly_album_chart
	 * 
	 * @param string $from
	 * @param string $to
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_weekly_album_chart($from = null, $to = null)
	{
		$params = '/user/' . $this->user . '/weeklyalbumchart.xml';

		if ($from !== null and $to !== null)
			$params .= '?' . http_build_query(array('from' => $from, 't=' => $to));

		return $this->api_call($params);
	}

	/**
	 * user_get_weekly_artist_chart
	 * 
	 * @param string $from
	 * @param string $to
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_weekly_artist_chart($from = null, $to = null)
	{
		$params = '/user/' . $this->user . '/weeklyartistchart.xml';

		if ($from !== null and $to !== null)
			$params .= '?' . http_build_query(array('from' => $from, 't=' => $to));

		return $this->api_call($params);
	}

	/**
	 * user_get_weekly_track_chart
	 * 
	 * @param string $from
	 * @param string $to
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function user_get_weekly_track_chart($from = null, $to = null)
	{
		$params = '/user/' . $this->user . '/weeklytrackchart.xml';

		if ($from !== null and $to !== null)
			$params .= '?' . http_build_query(array('from' => $from, 't=' => $to));

		return $this->api_call($params);
	}

	/**
	 * artist_get_related_artists
	 * 
	 * @param string $artist
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function artist_get_related_artists($artist)
	{
		return $this->api_call('/artist/' . $artist . '/similar.xml');
	}

	/**
	 * artist_get_top_fans
	 * 
	 * @param string $artist
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function artist_get_top_fans($artist)
	{
		return $this->api_call('/artist/' . $artist . '/fans.xml');
	}

	/**
	 * artist_get_top_tracks
	 * 
	 * @param string $artist
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function artist_get_top_tracks($artist)
	{
		return $this->api_call('/artist/' . $artist . '/toptracks.xml');
	}

	/**
	 * artist_get_top_albums
	 * 
	 * @param string $artist
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function artist_get_top_albums($artist)
	{
		return $this->api_call('/artist/' . $artist . '/topalbums.xml');
	}

	/**
	 * artist_get_top_tags
	 * 
	 * @param string $artist
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function artist_get_top_tags($artist)
	{
		return $this->api_call('/artist/' . $artist . '/toptags.xml');
	}

	/**
	 * album_get_info
	 * 
	 * @param string $artist
	 * @param string $album
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function album_get_info($artist, $album)
	{
		return $this->api_call('/album/' . $artist . '/' . $album . '/info.xml');
	}

	/**
	 * track_get_top_fans
	 * 
	 * @param string $artist
	 * @param string $track
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function track_get_top_fans($artist, $track)
	{
		return $this->api_call('/track/' . $artist . '/' . $track . '/fans.xml');
	}

	/**
	 * track_get_top_tags
	 * 
	 * @param string $artist
	 * @param string $track
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function track_get_top_tags($artist, $track)
	{
		return $this->api_call('/track/' . $artist . '/'. $track . '/toptags.xml');
	}

	/**
	 * tag_get_top_tags
	 * 
	 * @param string $tag
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function tag_get_top_tags($tag)
	{
		return $this->api_call('/tag/' . $tag . '/toptags.xml');
	}

	/**
	 * tag_get_top_albums
	 * 
	 * @param string $tag
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function tag_get_top_albums($tag)
	{
		return $this->api_call('/tag/' . $tag . '/topalbums.xml');
	}

	/**
	 * tag_get_top_artists
	 * 
	 * @param string $tag
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function tag_get_top_artists($tag)
	{
		return $this->api_call('/tag/' . $tag . '/topartists.xml');
	}

	/**
	 * tag_get_top_tracks
	 * 
	 * @param string $tag
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function tag_get_top_tracks($tag)
	{
		return $this->api_call('/tag/' . $tag . '/toptracks.xml');
	}

	/**
	 * group_get_weekly_chart_list
	 * 
	 * @param string $group
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function group_get_weekly_chart_list($group)
	{
		return $this->api_call('/group/' . $group . '/weeklychartlist.xml');
	}

	/**
	 * group_get_weekly_artist_chart_list
	 * 
	 * @param string $group
	 * @param string $from
	 * @param string $to
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function group_get_weekly_artist_chart_list($group, $from = null, $to = null)
	{
		$params = '/group/' . $group . '/weeklyartistchart.xml';

		if ($from !== null and $to !== null)
			$params .= '?' . http_build_query(array('from' => $from, 't=' => $to));

		return $this->api_call($params);
	}

	/**
	 * group_get_weekly_track_chart_list
	 * 
	 * @param string $group
	 * @param string $from
	 * @param string $to
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function group_get_weekly_track_chart_list($group, $from = null, $to = null)
	{
		$params = '/group/' . $group . '/weeklytrackchart.xml';

		if ($from !== null and $to !== null)
			$params .= '?' . http_build_query(array('from' => $from, 't=' => $to));

		return $this->api_call($params);
	}

	/**
	 * group_get_weekly_album_chart_list
	 * 
	 * @param string $group
	 * @param string $from
	 * @param string $to
	 * @return object SimpleXMLElement Object
	 * @access public
	 * 
	 */
	public function group_get_weekly_album_chart_list($group, $from = null, $to = null)
	{
		$params = '/group/' . $group . '/weeklyalbumchart.xml';

		if ($from !== null and $to !== null)
			$params .= '?' . http_build_query(array('from' => $from, 't=' => $to));

		return $this->api_call($params);
	}

	/**
	 * api_call
	 * 
	 * @param string $api_url
	 * @return object SimpleXMLElement Object
	 * @access protected
	 * 
	 */
	protected function api_call($api_url)
	{
		if ( ! $result = parent::api_call($api_url))
			throw new Kohana_User_Exception('AudioScrobbler Driver', Kohana::lang('service.invalid_response', $this->last_api_call(), $this->last_status_code()));

		$xml = simplexml_load_string($result);

		if (false === $xml)
			throw new Kohana_User_Exception('AudioScrobbler Driver', Kohana::lang('service.xml_parse_error'));

		return $xml;
	}

} //End Audioscrobbler Driver